﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Revis.VClinicNet.App.Internal;
using Revis.VClinicNet.App.Internal.Dto;
using Revis.VClinicNet.App.Internal.Dto.Validation;
using Revis.VClinicNet.UI.Internal.Mvc.Extensions;
using Revis.VClinicNet.UI.Internal.Mvc.Models;
using Revis.VClinicNet.Core.Domain.Credentials;
using Revis.VClinicNet.UI.Internal.Mvc.Infrastructure;

namespace Revis.VClinicNet.UI.Internal.Mvc.Controllers
{
    public class PatientController : Infrastructure.ControllerBase
    {
        private IPatientService _patientService = null;
        private IDoctorService _doctorService = null;

        public PatientController(IPatientService ips, IDoctorService ids) :
            base("Patient")
        {
            _patientService = ips;
            _doctorService = ids;
        }

        #region Actions

        /// <summary>
        /// Index action for recepcionist
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Recepcionist)]
        public ActionResult IndexR()
        {
            return View();
        }

        /// <summary>
        /// Index action for doctor
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Doctor)]
        public ActionResult IndexD()
        {
            return View();
        }

        /// <summary>
        /// Create empty patient form
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Recepcionist)]
        public ActionResult Create()
        {
            return View(new PatientCreateModel(_doctorService.ListAll()));
        }

        /// <summary>
        /// Send filled patient model to core and show errors if necessary
        /// </summary>
        /// <param name="patientCreateDto">filled model</param>
        /// <returns></returns>
        [HttpPost]
        [HistoryBackLinked(Type = BackLinkType.ModifyForm)]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Recepcionist)]
        public ActionResult Create(PatientCreateDto patientCreateDto)
        {

            try {
                long id = _patientService.Create(patientCreateDto);
                return RedirectToAction("Detail", new { id = id });
            } catch (ValidationException ve) {
                ModelState.AddModelErrors(ve);
            } catch (ClinicException ce) {
                ModelState.AddErrorMessage(ce.Message);
            }
            return View(new PatientCreateModel(patientCreateDto, _doctorService.ListAll()));
        }

        /// <summary>
        /// Create edit patient form
        /// </summary>
        /// <param name="id">patient id to edit</param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Recepcionist)]
        public ActionResult Edit(long id)
        {
            PatientEditDto patientEditDto = _patientService.Find<PatientEditDto>(id);
            if (patientEditDto == null) {
                return ErrorView("Nie znaleziono pacjenta", "Edit");
            }
            return View(new PatientEditModel(patientEditDto, _doctorService.ListAll()));
        }

        /// <summary>
        /// Send patient edit model to core and show errors if necessary
        /// </summary>
        /// <param name="patientEditDto">filled patient edit model</param>
        /// <returns></returns>
        [HttpPost]
        [HistoryBackLinked(Type = BackLinkType.ModifyForm)]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Recepcionist)]
        public ActionResult Edit(PatientEditDto patientEditDto)
        {
            try {
                long id = _patientService.Edit(patientEditDto);
                return RedirectToAction("Detail", new { id = id });
            } catch (ValidationException ve) {
                ModelState.AddModelErrors(ve);
            } catch (ClinicException ce) {
                ModelState.AddErrorMessage(ce.Message);
            }
            return View(new PatientEditModel(patientEditDto, _doctorService.ListAll()));
        }

        /// <summary>
        /// Patient detail action
        /// </summary>
        /// <param name="id">patient id</param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Doctor | WorkerUserRole.Recepcionist)]
        public ActionResult Detail(long id)
        {
            PatientDto patient = _patientService.Find<PatientDto>(id);
            if (patient == null) {
                return ErrorView("Nie znaleziono pacjenta", "Detail");
            }
            return View(patient);
        }

        /// <summary>
        /// Search patients and return result in json format
        /// </summary>
        /// <param name="field">name of field to search</param>
        /// <param name="value">value searched field</param>
        /// <returns></returns>
        [HttpPost]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Doctor | WorkerUserRole.Recepcionist)]
        public JsonResult JsonSearch(string field, string value)
        {
            IList<PatientInfoDto> patients = _patientService.FindBy<PatientInfoDto>(field, value);
            return Json(patients, JsonRequestBehavior.AllowGet);
        }

        #endregion

    }
}
